﻿<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>3D折叠图文展示效果</title>

<link type="text/css" href="css/style.css" rel="stylesheet" />

</head>
<body>

<div class="wrapper loading">
  <div class="destination folded">
    <h1>Iceland</h1>
    <hr/>
    <p class="caption">Fire and ice</p>
    <button>查看详情</button><img src="img/1.jpg" alt="Beautiful Iceland"/>
  </div>
  <div class="destination folded">
    <h1>Canada</h1>
    <hr/>
    <p class="caption">Genuine wilderness</p>
    <button>查看详情</button><img src="img/2.jpg" alt="Beautiful Canada"/>
  </div>
  <div class="destination folded">
    <h1>Norway</h1>
    <hr/>
    <p class="caption">Arctic gateway</p>
    <button>查看详情</button><img src="img/3.jpg" alt="Beautiful Norway"/>
  </div>
  <div class="destination folded">
    <h1>Greenland</h1>
    <hr/>
    <p class="caption">Epic landscapes</p>
    <button>查看详情</button><img src="img/4.jpg" alt="Beautiful Greenland"/>
  </div>
</div>

<script type="text/javascript">
class Carousel {
  static getDest(element) {
    if (!(element instanceof Element)) return;
    if (element === document.documentElement) return;
    if (element.classList.contains("destination")) return element;
    return Carousel.getDest(element.parentElement);
  }

  constructor(element) {
    this.wrapperElement = element;
    this.dests = [...element.querySelectorAll(".destination")];
    this.active = null;
    this.update();
    this.wrapperElement.classList.remove("loading");

    this.wrapperElement.addEventListener("mouseover", (event) => {
      const dest = Carousel.getDest(event.target);
      if (typeof dest === "undefined") return;
      if (dest === this.dests[this.active]) return;
      this.activate(dest);
    });

    this.wrapperElement.addEventListener(
      "mouseleave",
      throttle((event) => {
        console.log("mouseleave happening");
        if (event.target === this.wrapperElement) this.deactivate();
      }, 500)
    );
  }

  getIndex(dest) {
    if (!this.dests.includes(dest)) return;
    let i = 0;
    for (let currentDest of this.dests) {
      if (dest === currentDest) {
        return i;
      }
      i++;
    }
  }

  activate(dest) {
    this.active = this.getIndex(dest) ?? null;
    this.update();
  }

  deactivate() {
    this.active = null;
    this.update();
  }

  update() {
    this.dests.forEach((dest, index) => {
      dest.className = "destination";

      if (index === this.active) {
        dest.classList.add("unfolded", isOdd(index) ? "back" : "front");
      } else {
        dest.classList.add("folded");

        if (this.active === null || index < this.active) {
          dest.classList.add(isOdd(index) ? "right" : "left");
        } else if (index > this.active) {
          dest.classList.add(isOdd(index) ? "left" : "right");
        }
      }
    });
  }
}

function isOdd(value) {
  return value % 2 === 0;
}

const carousel = new Carousel(document.querySelector(".wrapper"));
</script>

</body>
</html>
